﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//using ExchangeMail;
using System.Net;
using System.ComponentModel;
using System.Net.Mail;
using System.Runtime.Remoting.Messaging;

namespace CRM.UTIL
{
    /// <summary>
    /// 邮件发送公用类
    /// XXXXXXXXX
    /// 2014.3.28
    /// </summary>
    public class MailSend
    {
        #region 属性

        /// <summary>
        /// 多个收信人 Mail ，以分号分隔
        /// </summary>
        public string To
        {
            set { this.to = value; }
        }private string to = "";

        /// <summary>
        /// 抄送人 Mail，以分号分隔
        /// </summary>
        public string Cc
        {
            set { this.cc = value; }
        }private string cc = "";

        /// <summary>
        /// 密送人 Mail，以分号分隔
        /// </summary>
        public string Bcc
        {
            set { this.bcc = value; }
        }private string bcc = "";

        /// <summary>
        /// 邮件标题
        /// </summary>
        public string Subject
        {
            set { this.subject = value; }
        }private string subject = "";

        /// <summary>
        /// 邮件内容
        /// </summary>
        public string Body
        {
            set { this.body = value; }
        }private string body = "";

        #endregion

        //委托声明
        private delegate void DelegateAsync(System.Net.Mail.SmtpClient smtp,System.Net.Mail.MailMessage msg);   


        public MailSend()
        {
        }

        /// <summary>
        /// CRM邮件异步发送（委托）
        ///XXXXXXXXX
        ///2014.3.28
        /// </summary>
        public bool AsyncSend()
        {
            try
            {
                int port = 25;
                int.TryParse(System.Configuration.ConfigurationManager.AppSettings["MailServerPort"], out port);
                System.Net.Mail.SmtpClient smc = new System.Net.Mail.SmtpClient(
                    System.Configuration.ConfigurationManager.AppSettings["MailServer"],
                    port);
                System.Net.NetworkCredential myCred = new System.Net.NetworkCredential(
                  System.Configuration.ConfigurationManager.AppSettings["MailAccount"],
                  System.Configuration.ConfigurationManager.AppSettings["MailPassword"],
                  System.Configuration.ConfigurationManager.AppSettings["MailDomain"]
                    );
                smc.Credentials = myCred;

                System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
                msg.From = Common.GetAddress(System.Configuration.ConfigurationManager.AppSettings["MailFrom"]);
                msg.HeadersEncoding = System.Text.Encoding.UTF8;
                foreach (System.Net.Mail.MailAddress ma in Common.CollectAddress(this.to))
                { msg.To.Add(ma); }
                foreach (System.Net.Mail.MailAddress ma in Common.CollectAddress(this.cc))
                { msg.CC.Add(ma); }
                foreach (System.Net.Mail.MailAddress ma in Common.CollectAddress(this.bcc))
                { msg.Bcc.Add(ma); }

                msg.Subject = this.subject;
                msg.BodyEncoding = System.Text.Encoding.UTF8;
                msg.Body = this.body;
                msg.IsBodyHtml = true;              

                //利用委托进行邮件发送
                DelegateAsync da = new DelegateAsync(AsyncMail);//定义委托
                AsyncCallback ac = new AsyncCallback(client_SendCompleted);  //回调事件
                da.BeginInvoke(smc,msg, ac, da); //调用委托方法             
              
             
                return true;
            }
            catch (Exception ex)
            {
                Common.LogErrorMsg("邮件发送出错：" + ex.Message + "\r\n" + ex.StackTrace, "");
                return false;
            }
        }

        /// <summary>
        /// 异步邮件发送完成
        /// XXXXXXXXX
        /// 2014.3.28
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void client_SendCompleted(IAsyncResult iar)
        {
            AsyncResult ar = (AsyncResult) iar;
            DelegateAsync dn = ar.AsyncDelegate as DelegateAsync;
            dn.EndInvoke(iar);
        }

        /// <summary>
        /// 委托方法：邮件发送
        /// XXXXXXXXX
        /// </summary>
        /// <param name="smtp">传输协议</param>
        /// <param name="msg">邮件实例</param>
        private void AsyncMail(System.Net.Mail.SmtpClient smtp, System.Net.Mail.MailMessage msg)
        {
            smtp.SendCompleted +=new SendCompletedEventHandler(smtp_SendCompleted);
            object userState = msg;
            smtp.SendAsync(msg, userState);//发送邮件        
        }

        /// <summary>
        /// 异步邮件发送完成的事件
        /// XXXXXXXXX
        /// 2014.3.28
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public static void smtp_SendCompleted(object sender, AsyncCompletedEventArgs e)
        {
            bool mailSent = true;

            System.Net.Mail.MailMessage mail = (System.Net.Mail.MailMessage)e.UserState;
            string subject = mail.Subject;
            string content = mail.Body;
            string to = string.Empty;
            if (mail.To != null && mail.To.Count > 0)
            {
                to = mail.To.Aggregate(to, (current, adr) => current + adr.Address);
            }
           
            if (e.Cancelled)
            {
                mailSent = false;
            }
            if (e.Error != null)
            {
                mailSent = false;
            }
            if (!mailSent)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("发送失败!  ");
                sb.Append("To:" + to);
                sb.Append("主题 :" + subject + " ");
                sb.Append("内容 :" + content);
                sb.Append("异常 :" + e.Error.ToString());
                Common.LogErrorMsg("异步发送邮件失败 " + System.DateTime.Now.ToString("yyyy-MM-dd") + sb.ToString(), "");

            }
            else
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("发送成功!  ");
                sb.Append("To:" + to);
                sb.Append("主题 :" + subject + " ");
                sb.Append("内容 :" + content);
                if (Convert.ToBoolean(System.Configuration.ConfigurationManager.AppSettings["MailLogFlag"]))
                    Common.LogErrorMsg("异步发送邮件成功 " + System.DateTime.Now.ToString("yyyy-MM-dd") + sb.ToString(), "");
            }

        }


    }
}
